home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Atari Compendium
/
The Atari Compendium (Toad Computers) (1994).iso
/
files
/
umich
/
utils
/
dircnt.arc
/
DIRCNT.C
next >
Wrap
C/C++ Source or Header
|
1987-01-18
|
9KB
|
281 lines
/*
dircnt.c
This is a program to count the number of
folders on a drive or drives to see if we're below
the awful 40 folder limit.Unlike the desktop it
does not use gemdos to access the directories
so that if we are over the limit running this shouldn't crash
the system.
David DeGeorge
princeton!idacrd!dld
ihnp4!acr011!dld
Jan 18,1987
This is released to the Public Domain and of course I don't
claim it won't wreck anything and I'm not responsible
if it does.
This will compile without change using the Mark Williams C compiler.
Others may have to make minor changes
*/
#include <stdio.h>
#include <osbind.h>
/* dir.h structure of directory entries from the IBM manual */
struct dir {
unsigned char name[11];
unsigned char attr ;
unsigned char reserv[10];
unsigned int crhms; /* create time hours min seconds */
unsigned int crmymd; /* create time year mon day */
unsigned int clustst; /* cluster start */
unsigned long len; /* file length */
};
/* nota bene clustst and len are given in 8086 format so bytes and words
have to be reversed using the routines conv86w and lfix */
typedef struct dir DIR;
/* from Mark Williams manual */
struct BPB_ {
short bp_secsize; /* Sector size bytes */
short bp_clulen; /* Cluster size sectors */
short bp_clusize; /* Cluster size bytes */
short bp_dirlen; /* Directory length sectors */
short bp_fatlen; /* FAT length sectors */
short bp_fatsect;/* Second FAT sector number */
short bp_datsect; /* First data sector */
short bp_clusters; /* Number of clusters on the disk */
short bp_flags;
};
typedef struct BPB_ BPB;
/* globals */
int *nufat; /* will hold the FAT table */
int *rootbuff; /* will hold the buffer for the root directory */
int dirnum=0; /* number of directories */
int recd= 0; /* recursion depth */
BPB *bpb; /* ptr to current disk parameter block */
unsigned int disk; /* current disk */
unsigned int endclust[]={ 0xff8,0xffff}; /* last cluster values */
/* Directories are read recursively up to 16 deep ( will this ever happen?)
since the cluster buffer is 1K we need a pretty big stack.
*/
long _stksize = 20000L;
main(argc,argv)
char **argv ;
{
int size;
unsigned int nextclst();
int rootlen,rootst,i,j;
int atemp,tot;
DIR *root;
DIR sdir;
int drlist[16],numdr;
long drvmask;
tot=0;
numdr=0;
drvmask=Drvmap(); /* which drives are installed ? */
if ( argc > 1){ /* use the arguments */
for ( i = 1 ; i < argc ; i++ ){
atemp=toupper(argv[i][0])-'A'; /* check the drive
is installed */
if ( ( drvmask >> atemp) & 1){
drlist[i-1]=atemp;
numdr++;
}
else
printf("Drive %c is not installed\n",argv[i][0]);
}
}
else /* no arguments just do the hard drive */
{
atemp = drvmask >> 2 ; /* start at drive C and
go up consecutively */
i=0;
while ( atemp & 1 ) {
drlist[i]=i+2;
numdr++;
atemp >>= 1;
i++;
}
}
/* Now we have a list of drives to do */
for ( i=0 ; i < numdr ;i++){ /* main loop */
dirnum=0;
disk = drlist[i];
bpb = ( BPB *) Getbpb(disk); /* get disk info */
size = bpb ->bp_fatlen; /* fatlen in sectors */
if ( i > 0 )free(nufat);
nufat = (int *)malloc(size*(bpb -> bp_secsize));
if ( nufat == ( int *) 0 ) {
printf("Can't malloc space for the FAT table\n");
exit(1);
}
if(Rwabs(0,nufat,size,1,disk) < 0L )diskerr(); /* read in fat table */
if ( i > 0) free( rootbuff);
rootbuff = ( int *) malloc( (bpb->bp_dirlen)*512 );
if ( rootbuff == (int * ) 0 ) {
printf("Can't malloc space for root directory\n");
exit(1);
}
/* read in the root directory */
rootst = bpb->bp_fatsect + bpb->bp_fatlen;
/* starting sector of the root */
if(Rwabs(0,rootbuff,bpb->bp_dirlen,rootst,disk) < 0L)diskerr();
/* rootlen is how many possible root directory entries */
rootlen =((bpb -> bp_secsize)/sizeof(DIR))* bpb->bp_dirlen;
root = ( DIR * )rootbuff;
dirnum++; /* count the root */
for ( j =0 ; j < rootlen ; j++) {
sdir = root[j] ; /* current entry */
if( sdir.name[0] == '\0' ) goto bye; /* end of space ever
allocated */
if ( sdir.attr & 0x10 ) { /* is it a directory */
if(sdir.name[0] == 0xE5 ) continue; /* erased */
if (sdir.name[0]=='.') continue; /* ignore . and .. */
recd++; /* increment recursion counter,
convert cluster start
to a 68000 integer, and read directory
*/
readdir(conv86w(sdir.clustst));
}
}
bye:
tot += dirnum; /* increment total */
printf("The total number of directories on drive %c is %d\n",'A'+disk,dirnum);
}
printf("The total number of directories counted is %d\n",tot);
printf("[RETURN]");getchar(); /* wait for a character */
}
unsigned nextclst(clst) /* returns the next cluster number as 68000 int */
unsigned int clst;
{
if(bpb -> bp_flags)return( conv86w(nufat[clst])); /* hard disk
16 bit FAT */
else
/* floppy disk
12 bit FAT
*/
{
unsigned int temp1,temp2;
char *p,*q;
temp1 = clst + ( clst >> 1); /* 1.5 * clst */
/* this next funny stuff is to access nufat
by byte offset. Since nufat is an array of ints
to word align it and make it easier to access in
the hard disk case we are paying now.
*/
q =( char *)nufat + temp1 ;
p= (char *)&temp2;
*p=*q;
*(p+1)=*(q+1);
temp2 = conv86w(temp2);
/* if clst is even take the bottom order twelve bits
if clst is odd take the top order 12 bits. This
is straight from the IBM-PC manual
*/
if (!( clst & 1) ) return( 0xFFF & temp2);
else return ( 0xFFF & ( temp2 >> 4 ));
}
}
long lfix(j) /* make an 8086 long int a 68000 long int */
long j; /* swap the hi-lo words and the bytes within the words */
{
long temp1,temp2;
int *k,*l;
temp1 = j;
k= (int *)&temp1;
l=(int *)&temp2;
*(l+1)= conv86w(*k);
*l = conv86w(*(k+1));
return(temp2);
}
conv86w(i) /* swap bytes this is in MWC library but included */
{ /* for completeness */
char *p,*q;
int k,j;
k=i;
p=(char *)&k;
q=(char *)&j;
*q = *( p+1);
*(q+1) = *(p);
return(j);
}
readdir(clust) /* readin a directory given the starting cluster */
{
int buff[512]; /* for all our supposed portability this is */
int i; /* the size of a cluster can't malloc 'cause */
DIR *dptr; /* we want it on the stack so we can be recursive */
DIR sdir;
int dirl;
dirl = (bpb->bp_clusize)/sizeof(DIR);/* how many dir ents in cluster */
dirnum++ ; /* increment global counter */
do {
dptr=( DIR *)buff;
reclst(buff,clust); /* read cluster into buffer */
for ( i=0 ; i < dirl ; i++) {
sdir = dptr[i];
if